package org.jeecg.modules.lab.items.controller;


import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import freemarker.template.TemplateException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.cronJob.MyEnum;
import org.jeecg.common.cronJob.entity.LabCronJob;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.TokenServess;
import org.jeecg.modules.lab.cronJob.service.ILabCronJobService;
import org.jeecg.modules.lab.device.entity.LabDevice;
import org.jeecg.modules.lab.device.service.ILabDeviceService;
import org.jeecg.modules.lab.entrust.entity.*;
import org.jeecg.modules.lab.entrust.service.ILabEntrustItemsIndexService;
import org.jeecg.modules.lab.entrust.service.ILabEntrustItemsService;
import org.jeecg.modules.lab.entrust.service.ILabEntrustSampleService;
import org.jeecg.modules.lab.entrust.service.ILabWentrustService;
import org.jeecg.modules.lab.items.entity.LabItemsBasis;
import org.jeecg.modules.lab.items.ibasis.service.ILabItemsBasisService;
import org.jeecg.modules.lab.items.record.service.*;
import org.jeecg.modules.lab.items.task.service.ILabTaskAllotService;
import org.jeecg.modules.lab.items.vo.*;
import org.jeecg.modules.lab.notify.entity.LabNotify;
import org.jeecg.modules.lab.notify.service.ILabNotifyService;
import org.jeecg.modules.lab.sample.record.service.ILabSampleRecordService;
import org.jeecg.modules.lab.utensil.entity.LabUtensil;
import org.jeecg.modules.lab.utensil.service.ILabUtensilService;
import org.jeecg.modules.lab.util.NumberUtil;
import org.jeecg.modules.lab.util.wordUtil.WordCreateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;


/**
 * @Description: 任务分配Controller
 * @Author: jeecg-boot
 * @Date: 2023-08-10
 * @Version: V1.0
 */
@Api(tags = "实验项目")
@RestController
@RequestMapping("/items/labTaskAllot")
@Slf4j
public class LabTaskAllotController extends JeecgController<LabTaskAllotPage, ILabTaskAllotService> {

    @Autowired
    private ILabTaskAllotService iLabTaskAllotService;

    @Autowired
    private ILabWentrustService iLabWentrustService;

    @Autowired
    private ILabEntrustItemsService labEntrustItemsService;

    @Autowired
    private ILabSampleRecordService labSampleRecordService;

    @Autowired
    private ILabItemsRecordSampleService labItemsRecordSampleService;

    @Autowired
    private ILabItemsRecordDeviceService labItemsRecordDeviceService;

    @Autowired
    private ILabItemsRecordNormService labItemsRecordNormService;

    @Autowired
    private ILabItemsRecordTargetService labItemsRecordTargetService;

    @Autowired
    private ILabItemsRecordPersonService labItemsRecordPersonService;

    @Autowired
    private ILabItemsRecordBasicsService labItemsRecordBasicsService;

    @Autowired
    private ILabItemsRecordReportService labItemsRecordReportService;

    @Autowired
    private ILabItemsBasisService labItemsBasisService;

    @Autowired
    private ILabNotifyService labNotifyService;

    @Autowired
    private ILabCronJobService labCronJobService;

    @Autowired
    private ILabEntrustSampleService labEntrustSampleService;

    /**
     * 注入线程池
     */
    @Resource(name = "executorService")
    private ExecutorService threadExecutor;

    @Autowired
    private ILabDeviceService labDeviceService;

    @Autowired
    private ILabUtensilService labUtensilService;

    @Autowired
    private ILabEntrustItemsIndexService labEntrustItemsIndexService;


    @Autowired
    private WordCreateUtils wordCreateUtils;

    /**
     * 分页列表查询
     *
     * @param labTaskAllotPage
     * @param pageNo
     * @param pageSize
     * @return
     */
    @ApiOperation(value = "实验项目-委托、监督列表查询", notes = "实验项目-委托、监督列表查询")
    @GetMapping(value = "/taskList")
    public Result<IPage<LabTaskAllotPage>> queryTaskPageList(LabTaskAllotPage labTaskAllotPage,
                                                             @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                             @RequestParam(name = "pageSize", defaultValue = "50") Integer pageSize,
                                                             @RequestParam(name = "entName", defaultValue = "") String entName,
                                                             @RequestParam(name = "sampleType", defaultValue = "") String sampleType) {
        String allotStatus = "";
        String billStatus = "";
        String auditId = "";
        String ratifyId = "";
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        String userId = loginUser.getId();
        List<LabTaskAllotPage> pageList = iLabTaskAllotService.getWTaskLists(entName, sampleType, allotStatus, billStatus, auditId, ratifyId, userId, labTaskAllotPage.getHandlDate(), labTaskAllotPage.getHandler());
        IPage<LabTaskAllotPage> page = new Page<>(pageNo, pageSize);
        page.setRecords(pageList);
        page.setTotal(pageList.size());
        return Result.OK(page);
    }


    /**
     * 报告列表查询
     *
     * @param pageNo
     * @param pageSize
     * @return
     */
    @ApiOperation(value = "实验报告-报告列表查询", notes = "实验项目-报告列表查询")
    @GetMapping(value = "/reportList")
    public Result<IPage<LabTaskAllotPage>> queryTaskReportList(@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                               @RequestParam(name = "pageSize", defaultValue = "50") Integer pageSize,
                                                               @RequestParam(name = "entName", defaultValue = "") String entName,
                                                               @RequestParam(name = "sampleType", defaultValue = "") String sampleType,
                                                               @RequestParam(name = "billStatus", defaultValue = "") String billStatus) {
        String allotStatus = "";
        String chiefId = "";
        String auditId = "";
        String ratifyId = "";
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        String userId = loginUser.getId();
//        String userName = loginUser.getRealname();
        if ("待编辑".equals(billStatus)) {
            chiefId = userId;
        } else if ("待审核".equals(billStatus)) {
            auditId = userId;
        } else if ("待批准".equals(billStatus)) {
            ratifyId = userId;
        }
        List<LabTaskAllotPage> pageListA = iLabTaskAllotService.getWReportLists(entName, sampleType, allotStatus, billStatus, chiefId, auditId, ratifyId, userId);
        List<LabTaskAllotPage> pageListB = iLabTaskAllotService.getRecordReportList(entName, sampleType, allotStatus, billStatus, chiefId, auditId, ratifyId, userId);
        List<LabTaskAllotPage> pageListC = new ArrayList<>();
        pageListC.addAll(pageListA);
        pageListC.addAll(pageListB);
        IPage<LabTaskAllotPage> page = new Page<>(pageNo, pageSize);
        page.setRecords(pageListC);
        page.setTotal(pageListC.size());
        return Result.OK(page);
    }


    /**
     * 自动分配任务（1）
     *
     * @param mId
     * @return
     */
    @ApiOperation(value = "实验项目-委托、监督任务自动分配", notes = "实验项目-委托、监督任务自动分配")
    @GetMapping(value = "/autoAllot")
    public Result<LabTaskUserPage> autoAllot(@RequestParam(name = "mId", required = true) String mId) {
        List<LabEntrustItems> labEntrustItems = labEntrustItemsService.selectItemsByMainId(mId);
        if (labEntrustItems.size() <= 0) {
            return Result.error("未找到对应数据");
        }
        String midId = labEntrustItems.get(0).getMidTypeId();
        LabTaskUserPage labTaskUserPage = iLabTaskAllotService.getAutoUser(midId);
        return Result.OK(labTaskUserPage);
    }

    /**
     * 自动分配任务（2）
     *
     * @param mId
     * @return
     */
    @ApiOperation(value = "实验项目-委托、监督任务自动分配", notes = "实验项目-委托、监督任务自动分配")
    @GetMapping(value = "/autoAllotTwo")
    public Result<List<LabItemsUsersPage>> autoAllotTwo(@RequestParam(name = "mId", required = true) String mId) {
        List<LabEntrustItems> labEntrustItems = labEntrustItemsService.selectItemsByMainId(mId);
        if (labEntrustItems.size() <= 0) {
            return Result.error("未找到对应数据");
        }
        List<LabItemsUsersPage> itemsUsersPages = iLabTaskAllotService.getItemToUsers(labEntrustItems);
        return Result.OK(itemsUsersPages);
    }


    /**
     * 手动分配任务可用实验人员
     *
     * @param mId
     * @return
     */
    @ApiOperation(value = "实验项目-任务分配可用实验人", notes = "实验项目-任务分配可用实验人")
    @GetMapping(value = "/handleUsers")
    public Result<IPage<LabTaskUserPage>> handleUsers(@RequestParam(name = "mId", required = true) String mId, @RequestParam(name = "realname", required = false) String realname) {
        List<LabEntrustItems> labEntrustItems = labEntrustItemsService.selectItemsByMainId(mId);
        if (labEntrustItems.size() <= 0) {
            return Result.error("未找到对应数据");
        }
        String midId = labEntrustItems.get(0).getMidTypeId();
        List<LabTaskUserPage> labTaskUserPages = new ArrayList<>();
        List<LabTaskUserPage> labTaskUserPages2 = iLabTaskAllotService.getAutoUserList(midId);
        if (realname != null) {
            for (LabTaskUserPage labTaskUserPage : labTaskUserPages2) {
                if (labTaskUserPage.getRealname().contains(realname)) {
                    labTaskUserPages.add(labTaskUserPage);
                }
            }
        } else {
            labTaskUserPages = labTaskUserPages2;
        }
        IPage<LabTaskUserPage> page = new Page<>(1, 100);
        page.setRecords(labTaskUserPages);
        page.setTotal(labTaskUserPages.size());
        return Result.OK(page);
    }


    /**
     * 可用实验人员(2)
     *
     * @param itemId
     * @return
     */
    @ApiOperation(value = "实验项目-可用实验人员(2)", notes = "实验项目-可用实验人员(2)")
    @GetMapping(value = "/handleUsersTwo")
    public Result<IPage<LabItemsUsersPage>> handleUsersTwo(@RequestParam(name = "itemId", required = true) String itemId, @RequestParam(name = "userName", defaultValue = "") String userName) {
//        List<LabItemsUsersPage> labTaskUserPages = iLabTaskAllotService.getItemToUserSkill(itemId, userName);
//        IPage<LabItemsUsersPage> page = new Page<>(1, 100);
//        page.setRecords(labTaskUserPages);
//        page.setTotal(labTaskUserPages.size());
        return Result.OK(null);
    }

    /**
     * 可用实验人员(3)
     *
     * @param itemId
     * @return
     */
    @ApiOperation(value = "实验项目-可用实验人员(3)", notes = "实验项目-可用实验人员(3)")
    @GetMapping(value = "/handleUsersThree")
    public Result<List<LabItemsUsersPage>> handleUsersThree(@RequestParam(name = "itemId", required = true) String itemId, @RequestParam(name = "basisId") String basisId, @RequestParam(name = "userName", defaultValue = "") String userName) {

        List<LabItemsUsersPage> labTaskUserPages = iLabTaskAllotService.getItemToUserSkill(itemId, basisId, userName);
        List<LabItemsUsersPage> labTaskUserTree = new ArrayList<>();
        labTaskUserTree = iLabTaskAllotService.setLabUserTree(labTaskUserTree);
        List<LabItemsUsersPage> labTaskUserA = new ArrayList<>();
        List<LabItemsUsersPage> labTaskUserB = new ArrayList<>();
        List<LabItemsUsersPage> labTaskUserC = new ArrayList<>();
        List<LabItemsUsersPage> labTaskUserD = new ArrayList<>();
        for (LabItemsUsersPage user : labTaskUserPages) {
            String parentId = user.getParentId();
            if ("1".equals(parentId)) {
                labTaskUserA.add(user);
            } else if ("2".equals(parentId)) {
                labTaskUserB.add(user);
            } else if ("3".equals(parentId)) {
                labTaskUserC.add(user);
            } else {
                labTaskUserD.add(user);
            }
        }
        for (LabItemsUsersPage userTree : labTaskUserTree) {
            String userId = userTree.getId();
            if ("1".equals(userId)) {
                userTree.setChildren(labTaskUserA);
            } else if ("2".equals(userId)) {
                userTree.setChildren(labTaskUserB);
            } else if ("3".equals(userId)) {
                userTree.setChildren(labTaskUserC);
            } else {
                userTree.setChildren(labTaskUserD);
            }
        }
        return Result.OK(labTaskUserTree);
    }


    /**
     * 提交任务分配
     *
     * @param labTaskItemsPage
     * @return
     */
    @AutoLog(value = "实验项目-提交任务分配")
    @ApiOperation(value = "实验项目-提交任务分配", notes = "实验项目-提交任务分配")
    @RequestMapping(value = "/submitAllot", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<String> submitAllot(@RequestBody LabTaskItemsPage labTaskItemsPage) throws Exception {
        iLabTaskAllotService.updateMain(labTaskItemsPage);
        String taskId = labTaskItemsPage.getId();
        LabWentrust labWentrust = iLabWentrustService.getById(taskId);
        String sortName = labWentrust.getSampleSort();
        List<LabEntrustItems> labEntrustItems = labTaskItemsPage.getLabEntrustItems();
        for (int i = 0; i < labEntrustItems.size(); i++) {
            LabEntrustItems entrustItems = labEntrustItems.get(i);
            //分配时将任务消息写到消息表中
            String samNum = entrustItems.getSamNum();
            String itemName = entrustItems.getItemName();
            String notTitle = "实验";
            String itemId = entrustItems.getItemId();
            String taskName = "你有一个样品编号：" + samNum + "的[" + sortName + "]-[" + itemName + "]待检实验";
            String entrustId = entrustItems.getEntrustId();
            String[] userIds = entrustItems.getUserId().split(",");
            for (String userId : userIds) {
                makeNotify(sortName, itemName, notTitle, taskId, taskName, entrustId, userId, itemId);
            }
        }

        if (MyEnum.sync) {
            long time = new Date().getTime();
            List<LabCronJob> jobs = new ArrayList<>();
            jobs.add(new LabCronJob("lab_notify", "0", time, 1));
            if ("委托检验".equals(labTaskItemsPage.getEntrustType())) {
                jobs.add(new LabCronJob("lab_wentrust", "1", time, 2));
            } else if ("监督检验".equals(labTaskItemsPage.getEntrustType())) {
                jobs.add(new LabCronJob("lab_wsupervise", "1", time, 2));
            }
            if (labTaskItemsPage.getLabEntrustItems() != null && labTaskItemsPage.getLabEntrustItems().size() > 0) {
                jobs.add(new LabCronJob("lab_entrust_items", "1", time, 3));
            }
            labCronJobService.saveBatch(jobs);
        }
        return Result.OK("任务分配完成!");
    }


    /**
     * 调整任务分配
     *
     * @param labEntrustItems
     * @return
     */
    @AutoLog(value = "实验项目-调整任务分配")
    @ApiOperation(value = "实验项目-调整任务分配", notes = "实验项目-调整任务分配")
    @RequestMapping(value = "/updateTaskItems", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<String> updateTaskItems(@RequestBody LabEntrustItems labEntrustItems) throws Exception {
        iLabTaskAllotService.updateEntrustItems(labEntrustItems);

        String sortName = labEntrustItems.getMidTypeName();
        String taskId = labEntrustItems.getEntrustId();

        //分配时将任务消息写到消息表中
        String samNum = labEntrustItems.getSamNum();
        String itemName = labEntrustItems.getItemName();
        String notTitle = "实验";
        String itemId = labEntrustItems.getItemId();
        String taskName = "你有一个样品编号：" + samNum + "的[" + sortName + "]-[" + itemName + "]待检实验";
        String entrustId = labEntrustItems.getEntrustId();
        String[] userIds = labEntrustItems.getUserId().split(",");
        for (String userId : userIds) {
            makeNotify(sortName, itemName, notTitle, taskId, taskName, entrustId, userId, itemId);
        }

        if (MyEnum.sync) {
            long time = new Date().getTime();
            List<LabCronJob> jobs = new ArrayList<>();
            jobs.add(new LabCronJob("lab_notify", "0", time, 1));
            if (labEntrustItems != null) {
                jobs.add(new LabCronJob("lab_entrust_items", "1", time, 2));
            }
            labCronJobService.saveBatch(jobs);
        }
        return Result.OK("任务分配调整完成!");
    }


    /**
     * 提交科研任务到实验检测
     *
     * @param labEntrustItemss
     * @return
     */
    @AutoLog(value = "提交科研任务到实验检测")
    @ApiOperation(value = "提交科研任务到实验检测", notes = "提交科研任务到实验检测")
    @RequestMapping(value = "/submitResearch", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<String> submitResearch(@RequestBody LabEntrustItems labEntrustItemss) throws Exception {
        iLabTaskAllotService.updateMainKy(labEntrustItemss);

        //分配时将任务消息写到消息表中
        //String notName = labEntrustItems.get(i).getSamName();
        String itemName = labEntrustItemss.getItemName();
        String itemId = labEntrustItemss.getItemId();
        String notTitle = "实验";
        String taskId = labEntrustItemss.getItemId();
        String taskName = "[科研任务]的" + itemName + "实验";
        //String entrustId = labEntrustItems.get(i).getEntrustId();//委托id
        String userId = labEntrustItemss.getUserId();
        makeNotify("", itemName, notTitle, taskId, taskName, labEntrustItemss.getId(), userId, itemId);
        return Result.OK("提交成功!");
    }


    /**
     * 创建消息
     *
     * @param notName   消息名称
     * @param itemName  任务名称
     * @param notTitle  消息标题
     * @param taskId    任务id
     * @param taskName  消息名称（展示）
     * @param entrustId 业务id
     * @param uerId     处理人id
     */
    private void makeNotify(String notName, String itemName, String notTitle, String taskId, String taskName, String entrustId, String uerId, String itemId) throws NoSuchAlgorithmException, IOException, InvalidKeyException {
        LabNotify labNotify = new LabNotify();
        labNotify.setNotName(notName);
        labNotify.setItemName(itemName);
        labNotify.setNotTitlle(notTitle);
        //todo:确认taskid是项目的id
        labNotify.setTaskId(taskId);
        labNotify.setTaskName(taskName);
        labNotify.setEntrustId(entrustId);
        labNotify.setItemId(itemId);
        labNotify.setUserId(uerId);
        labNotify.setNotStatus("未读");
        labNotify.setFinish(0);
        labNotify.setPubTime(new Date());
        labNotifyService.save(labNotify);
        /**
         * 线程
         */
        Callable<Boolean> c = () -> {
            try {
                //调即时通
                LoginUser loginUser = labNotifyService.byIdLogUser(uerId);
                //判断用户是否在数智天研系统中是否有账号，如果有发送消息，否则不发消息
                String tId = loginUser.getTId();
                if (!"".equals(tId) && tId != null) {
                    TokenServess tokenServess = new TokenServess();
                    String tokenServe = tokenServess.getTokenServe();
                    tokenServess.getSysmw(taskName, tId, tokenServe);
                }
            } catch (Exception e) {
            }
            return true;
        };
        threadExecutor.submit(c);
    }

    /**
     * 根据人员查询检测项目
     *
     * @return
     */
    @ApiOperation(value = "实验项目-根据人员查询检测项目", notes = "实验项目-根据人员查询检测项目")
    @GetMapping(value = "/getCheckItems")
    public Result<IPage<LabCheckItemsPage>> getCheckItems(@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                          @RequestParam(name = "pageSize", defaultValue = "50") Integer pageSize,
                                                          @RequestParam(name = "userId", defaultValue = "") String userId,
                                                          @RequestParam(name = "auditId", defaultValue = "") String auditId,
                                                          @RequestParam(name = "entrustType", defaultValue = "") String entrustType,
                                                          @RequestParam(name = "entName", defaultValue = "") String entName,
                                                          @RequestParam(name = "sampleType", defaultValue = "") String sampleType,
                                                          @RequestParam(name = "sampleSort", defaultValue = "") String sampleSort,
                                                          @RequestParam(name = "pubDate", defaultValue = "") String pubDate,
                                                          @RequestParam(name = "itemStatus", defaultValue = "") String itemStatus) {

        List<LabCheckItemsPage> labCheckItemsPages = iLabTaskAllotService.getCheckItems(userId, auditId, entrustType, entName, sampleType, sampleSort, itemStatus, pubDate);
        IPage<LabCheckItemsPage> page = new Page<>(pageNo, pageSize);
        page.setRecords(labCheckItemsPages);
        page.setTotal(labCheckItemsPages.size());
        return Result.OK(page);
    }

    @GetMapping(value = "/getOne")
    public Result getOne(@RequestParam String itemsId, @RequestParam String entrustId) {
        LabCheckItemsPage items = iLabTaskAllotService.getItems(itemsId, entrustId);
        return Result.ok(items);
    }

    /**
     * 报告审查数据
     *
     * @param entrustId
     * @return
     */
    @ApiOperation(value = "实验项目-报告审查数据", notes = "实验项目-报告审查数据")
    @GetMapping(value = "/getReportReviewData")
    public Result<LabReportReviewPage> getReportReviewData(@RequestParam(name = "entrustId", required = true) String entrustId) {

        LabReportReviewPage labReportReviewPage = new LabReportReviewPage();

        //1、实验报告数据
        LabItemsReportPage labItemsReportPage = new LabItemsReportPage();
        //1.1实验报告
        QueryWrapper<LabItemsRecordReport> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("task_id", entrustId);
        LabItemsRecordReport labItemsRecordReport = labItemsRecordReportService.getOne(queryWrapper);
        BeanUtils.copyProperties(labItemsRecordReport, labItemsReportPage);
        //1.1、项目实验数据
        QueryWrapper<LabEntrustItems> queryItemsWrapper = new QueryWrapper<>();
        queryItemsWrapper.eq("entrust_id", entrustId).orderByAsc("create_time");
        List<LabEntrustItems> labEntrustItemsList = labEntrustItemsService.list(queryItemsWrapper);

        List<LabEntrustItemsIndexPage> labEntrustItemsIndexList = labEntrustItemsIndexService.getItemsIndexByTaskId(entrustId);
        labItemsReportPage.setLabEntrustItemsIndexPageList(labEntrustItemsIndexList);

        //2、实验项目原始记录
        List<LabItemRecordPage> labItemRecordPageList = new ArrayList<>();
        String params = "";
        if (labEntrustItemsList.size() > 0) {
            for (LabEntrustItems item : labEntrustItemsList) {
                String taskItemId = item.getId();
                String itemId = item.getItemId();
                LabItemRecordPage labItemRecordPage = new LabItemRecordPage();
                labItemRecordPage.setItemName(item.getItemName());
                labItemRecordPage.setLabRecordSamList(labItemsRecordSampleService.handleSamData(entrustId, taskItemId, itemId));
                labItemRecordPage.setLabRecordDevList(labItemsRecordDeviceService.handleDevData(entrustId, taskItemId, itemId));
                labItemRecordPage.setLabRecordNormList(labItemsRecordNormService.handleNormData(entrustId, taskItemId, itemId));
                labItemRecordPage.setLabRecordTargList(labItemsRecordTargetService.handleTargData(entrustId, taskItemId, itemId));
                labItemRecordPage.setLabRecordPerList(labItemsRecordPersonService.handlePerData(entrustId, taskItemId, itemId));
//                labItemRecordPage = handleItemRecordData(labItemRecordPage, entrustId, itemId);
                labItemRecordPageList.add(labItemRecordPage);
                if ("".equals(params)) {
                    params = item.getEntrustType();
                }
            }

            String samName = labItemsReportPage.getSamName();
            String samNum = labItemsReportPage.getSamNum();
            String reportNumber = labItemsReportPage.getReportNum();
            String pdfFile = "/labPdf/" + samNum + "/" + samName + "-" + params + "-" + reportNumber + ".pdf";
            labItemsReportPage.setPfdFile(pdfFile);
            //把实验报告数据装入labReportReviewPage中
            labReportReviewPage.setLabItemsReportPage(labItemsReportPage);
            //把实验项目原始记录装入labReportReviewPage中
            labReportReviewPage.setLabItemRecordPageList(labItemRecordPageList);
            return Result.OK(labReportReviewPage);
        } else {
            return Result.error("未找到对应数据");
        }
    }


    /**
     * 实验记录数据
     *
     * @return
     */
    @ApiOperation(value = "实验项目-实验记录数据", notes = "实验项目-实验记录数据")
    @GetMapping(value = "/getItemsReportData")
    public Result<List<LabItemRecordPage>> getItemsReportData(@RequestParam(name = "entrustId", required = true) String entrustId) {
        QueryWrapper<LabEntrustItems> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("entrust_id", entrustId).orderByAsc("create_time");
        List<LabEntrustItems> labEntrustItemsList = labEntrustItemsService.list(queryWrapper);

        List<LabItemRecordPage> labItemRecordPageList = new ArrayList<>();

        if (labEntrustItemsList.size() > 0) {
            for (LabEntrustItems item : labEntrustItemsList) {
                // 执行操作
                String taskItemId = item.getId();
                String itemId = item.getItemId();
                LabItemRecordPage labItemRecordPage = new LabItemRecordPage();
                labItemRecordPage.setItemName(item.getItemName());
                labItemRecordPage.setLabRecordSamList(labItemsRecordSampleService.handleSamData(entrustId, taskItemId, itemId));
                labItemRecordPage.setLabRecordDevList(labItemsRecordDeviceService.handleDevData(entrustId, taskItemId, itemId));
                labItemRecordPage.setLabRecordNormList(labItemsRecordNormService.handleNormData(entrustId, taskItemId, itemId));
                labItemRecordPage.setLabRecordTargList(labItemsRecordTargetService.handleTargData(entrustId, taskItemId, itemId));
                labItemRecordPage.setLabRecordPerList(labItemsRecordPersonService.handlePerData(entrustId, taskItemId, itemId));
                labItemRecordPage = handleItemRecordData(labItemRecordPage, entrustId, taskItemId, itemId);
                labItemRecordPageList.add(labItemRecordPage);
            }
            return Result.OK(labItemRecordPageList);
        } else {
            return Result.error("未找到对应数据");
        }
    }


    /**
     * 根据检测项目查询记录数据
     *
     * @return
     */
    @ApiOperation(value = "实验项目-根据检测项目查询记录数据", notes = "实验项目-根据检测项目查询记录数据")
    @GetMapping(value = "/getItemsRecordData")
    public Result<LabItemRecordPage> getItemsRecordData(@RequestParam(name = "entrustId", required = true) String entrustId,
                                                        @RequestParam(name = "taskItemId", defaultValue = "") String taskItemId,
                                                        @RequestParam(name = "itemId", required = true) String itemId) {
        LabItemRecordPage labItemRecordPage = new LabItemRecordPage();
        labItemRecordPage.setLabRecordSamList(labItemsRecordSampleService.handleSamData(entrustId, taskItemId, itemId));
        labItemRecordPage.setLabRecordDevList(labItemsRecordDeviceService.handleDevData(entrustId, taskItemId, itemId));
        labItemRecordPage.setLabRecordNormList(labItemsRecordNormService.handleNormData(entrustId, taskItemId, itemId));
        labItemRecordPage.setLabRecordTargList(labItemsRecordTargetService.handleTargData(entrustId, taskItemId, itemId));
        labItemRecordPage.setLabRecordPerList(labItemsRecordPersonService.handlePerData(entrustId, taskItemId, itemId));
        labItemRecordPage = handleItemRecordData(labItemRecordPage, entrustId, taskItemId, itemId);
        return Result.OK(labItemRecordPage);
    }


    /**
     * 把检测基础数据赋值labItemRecordPage中
     *
     * @param labItemRecordPage
     * @param entrustId
     * @param itemId
     * @return
     * @oaram taskItemId
     */
    public LabItemRecordPage handleItemRecordData(LabItemRecordPage labItemRecordPage, String entrustId, String taskItemId, String itemId) {
        LabRecordBas recordBas = labItemsRecordBasicsService.getRecordBasOne(entrustId, taskItemId, itemId);
        labItemRecordPage.setAuditId(recordBas.getAuditId());
        labItemRecordPage.setAuditName(recordBas.getAuditName());
        for (LabRecordSam sams : labItemRecordPage.getLabRecordSamList()) {
            for (LabItemsRecordSample sam : sams.getItemsRecordSampleList()) {
                if ("sam_name".equals(sam.getFieldCode())) {
                    String samName = recordBas.getSamName();
                    if (samName != null && !"".equals(samName)) {
                        sam.setFieldValue(recordBas.getSamName());
                    }
                } else if ("sam_num".equals(sam.getFieldCode())) {
                    String samNum = recordBas.getSamNum();
                    if (samNum != null && !"".equals(samNum)) {
                        sam.setFieldValue(recordBas.getSamNum());
                    }
                } else if ("check_basis".equals(sam.getFieldCode())) {
                    //检测标准不显示编码，改为显示中文名称
//                    sam.setFieldValue(recordBas.getBasisNum());
                    if (sam.getFieldValue() == null || "".equals(sam.getFieldValue())) {
                        LabItemsBasis itemsBasis = labItemsBasisService.getById(recordBas.getBasisId());
                        if (itemsBasis != null) {
                            sam.setFieldValue(itemsBasis.getNum());
                        }
                    }

                } else if ("check_time".equals(sam.getFieldCode())) {
                    if (sam.getFieldValue() == null || "".equals(sam.getFieldValue())) {
                        sam.setFieldValue(DateUtils.getDate("yyyy-MM-dd"));
                    }

                }
            }
        }
        for (LabRecordPer pers : labItemRecordPage.getLabRecordPerList()) {
            for (LabItemsRecordPerson per : pers.getItemsRecordPersonList()) {
                if ("check_person".equals(per.getFieldCode()) || "person_value1".equals(per.getFieldCode())) {
                    per.setFieldValue(recordBas.getCheckPer());
                } else if ("audit_person".equals(per.getFieldCode()) || "person_value2".equals(per.getFieldCode())) {
                    per.setFieldValue(recordBas.getAuditName());
                }
            }
        }
        LabEntrustItems entrustItems = labEntrustItemsService.getOne(new LambdaQueryWrapper<LabEntrustItems>()
                .eq(LabEntrustItems::getEntrustId, entrustId).eq(LabEntrustItems::getItemId, itemId).eq(LabEntrustItems::getId, taskItemId));
        if (entrustItems != null) {
            labItemRecordPage.setSamUsed(entrustItems.getSamUsed());
            labItemRecordPage.setItemStatus(entrustItems.getItemStatus());
        }
        return labItemRecordPage;
    }

    /**
     * @param labItemRecordPage
     * @return
     */
    @AutoLog(value = "实验项目-更新项目检测原始数据")
    @ApiOperation(value = "实验项目-更新项目检测原始数据", notes = "实验项目-更新项目检测原始数据")
    @RequestMapping(value = "/saveOrUpdate", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<String> saveOrUpdate(@RequestBody LabItemRecordPage labItemRecordPage) throws NoSuchAlgorithmException, IOException, InvalidKeyException {

        String entrustId = labItemRecordPage.getEntrustId();
        String taskitemId = labItemRecordPage.getTaskItemId();
        String itemId = labItemRecordPage.getItemId();
        String itemStatus = labItemRecordPage.getItemStatus();

        // todo 查询实验项目
        QueryWrapper<LabEntrustItems> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("entrust_id", entrustId).eq("item_id", itemId).eq("id", taskitemId);
        List<LabEntrustItems> labEntrustItemsList = labEntrustItemsService.list(queryWrapper);
        if (labEntrustItemsList == null || labEntrustItemsList.size() <= 0) {
            return Result.error("未找到对应数据");
        } else {
            LabEntrustItems labEntrustItems = labEntrustItemsList.get(0);
            //1、更新样品信息
            List<LabRecordSam> labRecordSamList = labItemRecordPage.getLabRecordSamList();
            if (CollectionUtil.isNotEmpty(labRecordSamList)) {
                labRecordSamList.forEach(e -> {
                    List<LabItemsRecordSample> sampleList = e.getItemsRecordSampleList();
                    sampleList.forEach(sam -> {
                        sam.setSynFlag("1");
                    });
                });
                labItemsRecordSampleService.saveOrUpdate(entrustId, taskitemId, itemId, labRecordSamList);
            }
            //2、更新设备仪器信息
            List<LabItemsRecordDevice> labRecordDevList = labItemRecordPage.getLabRecordDevList();
            if (CollectionUtil.isNotEmpty(labRecordDevList)) {
                Date date = new Date();
                labRecordDevList.forEach(e -> {
                    long sTime = date.getTime();
                    long eTime = date.getTime();
                    long diffInMilliseconds = eTime - sTime;
                    long minutes = diffInMilliseconds / 6000;
                    if (minutes == 0) {
                        minutes = 1;
                    }
                    e.setRunTime(Long.toString(minutes));
                    e.setItemName(labEntrustItems.getItemName());
                    e.setUserId(labEntrustItems.getUserId());
                    e.setUserName(labEntrustItems.getUserName());
                    e.setSamName(labEntrustItems.getSamName());
                    e.setSynFlag("1");
                    e.setSyType(labEntrustItems.getEntrustType());
                });
                labItemsRecordDeviceService.saveOrUpdate(entrustId, taskitemId, itemId, labRecordDevList);
            }
            //3、更新检测条件信息
            List<LabRecordNorm> labRecordNormList = labItemRecordPage.getLabRecordNormList();
            if (CollectionUtil.isNotEmpty(labRecordNormList)) {
                labRecordNormList.forEach(e -> {
                    List<LabItemsRecordNorm> normList = e.getItemsRecordNormList();
                    normList.forEach(norm -> {
                        norm.setSynFlag("1");
                    });
                });
                labItemsRecordNormService.saveOrUpdate(entrustId, itemId, labRecordNormList);
            }
            //4、更新检测信息
            List<LabRecordTarg> labRecordTargList = labItemRecordPage.getLabRecordTargList();
            if (CollectionUtil.isNotEmpty(labRecordTargList)) {
                labRecordTargList.forEach(e -> {
                    List<LabItemsRecordTarget> targets = e.getItemsRecordTargetList();
                    targets.forEach(target -> {
                        target.setSynFlag("1");
                    });
                });
                labItemsRecordTargetService.saveOrUpdate(entrustId, itemId, labRecordTargList);
            }
            //5、更新检测人员信息
            List<LabRecordPer> labRecordPerList = labItemRecordPage.getLabRecordPerList();
            if (CollectionUtil.isNotEmpty(labRecordPerList)) {
                labRecordPerList.forEach(e -> {
                    List<LabItemsRecordPerson> personList = e.getItemsRecordPersonList();
                    personList.forEach(person -> {
                        person.setSynFlag("1");
                    });
                });
                labItemsRecordPersonService.saveOrUpdate(entrustId, itemId, labRecordPerList);
            }
            //6、更新实验项目的信息
            LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            labEntrustItems.setItemStatus(labItemRecordPage.getItemStatus());
            labEntrustItems.setItemFinishTime(DateUtils.getDate());
            labEntrustItems.setSynFlag("1");
            labEntrustItemsService.updateById(labEntrustItems);

            //todo 修改该实验消息的完成状态
            List<LabNotify> labNotifies = labNotifyService.list(new LambdaQueryWrapper<LabNotify>()
                    .eq(LabNotify::getEntrustId, labItemRecordPage.getEntrustId())
                    .eq(LabNotify::getTaskId, labItemRecordPage.getItemId())
                    .eq(LabNotify::getNotTitlle, "实验").eq(LabNotify::getUserId, loginUser.getId()));
            if (labNotifies != null) {
                for (LabNotify labNotify : labNotifies) {
                    labNotify.setFinish(1);
                    labNotifyService.updateById(labNotify);
                }
            }
            //增加新消息
            if ("待复核".equals(itemStatus)) {
                //todo 更新实验项目的检测指标结果
                generatResultPc(labEntrustItems.getId(), labEntrustItems.getBasisId(), labRecordTargList);

                //todo 更新样品状态
                labEntrustSampleService.updateSample(taskitemId);

                //todo 样品流传记录
                labSampleRecordService.addLabRecords(entrustId, labEntrustItems);
                String notName = labItemRecordPage.getSamName();
                String itemName = labItemRecordPage.getItemName();
                String notTitle = "实验复核";
                String taskName = "样品[" + notName + "]的" + itemName + "复核";
                String userId = labItemRecordPage.getAuditId();
                makeNotify(notName, itemName, notTitle, itemId, taskName, entrustId, userId, itemId);
            }


            if (MyEnum.sync) {
                //同步表信息
                long time = new Date().getTime();
                List<LabCronJob> jobs = new ArrayList<>();
                jobs.add(new LabCronJob("lab_items_record_sample", "1", time, 1));
                jobs.add(new LabCronJob("lab_items_record_device", "0", time, 2));
                jobs.add(new LabCronJob("lab_items_record_norm", "1", time, 3));
                jobs.add(new LabCronJob("lab_items_record_target", "1", time, 4));
                jobs.add(new LabCronJob("lab_items_record_person", "1", time, 5));
                jobs.add(new LabCronJob("lab_entrust_items", "1", time, 6));
                jobs.add(new LabCronJob("lab_entrust_items_index", "1", time, 7));
                jobs.add(new LabCronJob("lab_notify", "1", time, 8));
                jobs.add(new LabCronJob("lab_notify", "0", time, 9));
                jobs.add(new LabCronJob("lab_sample_record", "0", time, 10));
                jobs.add(new LabCronJob("lab_entrust_sample", "1", time, 11));
                labCronJobService.saveBatch(jobs);
            }
        }
        if ("待复核".equals(itemStatus)) {
            return Result.OK("实验完成！");
        } else {
            return Result.OK("保存成功！");
        }

    }


    /**
     * 实验项目-复核（同意、不同意）
     *
     * @param itemId
     * @param itemStatus
     * @return
     */
    @AutoLog(value = "实验项目-复核（同意、不同意）")
    @ApiOperation(value = "实验项目-复核（同意、不同意）", notes = "实验项目-复核（同意、不同意）")
    @DeleteMapping(value = "/auditCheckData")
    public Result<String> auditCheckData(@RequestParam(name = "entrustId", defaultValue = "") String entrustId,
                                         @RequestParam(name = "taskItemId", defaultValue = "") String taskItemId,
                                         @RequestParam(name = "itemId", defaultValue = "") String itemId,
                                         @RequestParam(name = "itemStatus", defaultValue = "") String itemStatus) throws TemplateException, IOException, IllegalAccessException {
        QueryWrapper<LabEntrustItems> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("entrust_id", entrustId).eq("item_id", itemId).eq("id", taskItemId);
        LabEntrustItems labEntrustItems = labEntrustItemsService.getOne(queryWrapper);
        if (labEntrustItems == null) {
            return Result.error("未找到对应数据");
        } else {
            String type = labEntrustItems.getEntrustType();
            if (("委托检验".equals(type) || "监督抽查".equals(type)) && "已实验".equals(itemStatus)) {
                labEntrustItems.setItemPdfUrl("/labpdf/" + labEntrustItems.getSamNum() + "/" + labEntrustItems.getItemName() + ".pdf");
            }
            labEntrustItems.setItemStatus(itemStatus);
            labEntrustItems.setSynFlag("1");
            //修改该实验消息的完成状态
            labEntrustItemsService.updateById(labEntrustItems);

            List<LabNotify> labNotifies = labNotifyService.list(new LambdaQueryWrapper<LabNotify>()
                    .eq(LabNotify::getEntrustId, entrustId)
                    .eq(LabNotify::getTaskId, itemId)
                    .eq(LabNotify::getNotTitlle, "实验复核"));
            if (labNotifies != null) {
                for (LabNotify labNotify : labNotifies) {
                    labNotify.setFinish(1);
                    labNotify.setSynFlag("1");
                    labNotifyService.updateById(labNotify);
                }
            }

            if (MyEnum.sync) {
                //同步表信息
                long time = new Date().getTime();
                List<LabCronJob> jobs = new ArrayList<>();
                jobs.add(new LabCronJob("lab_entrust_items", "1", time, 1));
                jobs.add(new LabCronJob("lab_notify", "1", time, 2));
                labCronJobService.saveBatch(jobs);
            }
            if ("已实验".equals(itemStatus)) {
                if ("委托检验".equals(type) || "监督抽查".equals(type)) {
                    wordCreateUtils.createWord(taskItemId, labEntrustItems.getSamNum());
                }
                return Result.OK("复核完成！");
            } else {
                return Result.OK("退回成功!");
            }
        }
    }


    /**
     * 根据检测项目查询记录数据
     *
     * @return
     */
    @ApiOperation(value = "实验项目-根据检测项目查询记录数据(APP)", notes = "实验项目-根据检测项目查询记录数据(APP)")
    @GetMapping(value = "/getItemsRecordDataApp")
    public Result<LabItemRecordApp> getItemsRecordDataApp(@RequestParam(name = "entrustId", required = true) String entrustId,
                                                          @RequestParam(name = "taskItemId") String taskItemId,
                                                          @RequestParam(name = "itemId", required = true) String itemId) {
        LabItemRecordApp labItemRecordApp = getLabItemRecord(entrustId, taskItemId, itemId);
        return Result.OK(labItemRecordApp);
    }

    /**
     * 处理数据
     *
     * @param entrustId
     * @param taskItemId
     * @param itemId
     * @return
     */
    public LabItemRecordApp getLabItemRecord(String entrustId, String taskItemId, String itemId) {
        LabItemRecordApp labItemRecordApp = new LabItemRecordApp();
        List<LabItemsRecordSample> labItemsRecordSamples = labItemsRecordSampleService.handleSamDataApp(entrustId, taskItemId, itemId);
        List<LabItemsRecordSampleVo> sampleVos = new ArrayList<>();
        labItemsRecordSamples.forEach(e -> {
            LabItemsRecordSampleVo sampleVo = new LabItemsRecordSampleVo();
            BeanUtils.copyProperties(e, sampleVo);
            sampleVos.add(sampleVo);
        });
        labItemRecordApp.setItemsRecordSampleList(sampleVos);
        labItemRecordApp.setItemsRecordDevList(labItemsRecordDeviceService.handleDevData(entrustId, taskItemId, itemId));
        labItemRecordApp.setItemsRecordNormList(labItemsRecordNormService.handleNormDataApp(entrustId, taskItemId, itemId));
        labItemRecordApp.setItemsRecordTargetList(labItemsRecordTargetService.handleTargDataApp(entrustId, taskItemId, itemId));
        labItemRecordApp.setItemsRecordPersonList(labItemsRecordPersonService.handlePerDataApp(entrustId, taskItemId, itemId));
        labItemRecordApp = handleItemRecordDataApp(labItemRecordApp, entrustId, taskItemId, itemId);


        LabEntrustItems labEntrustItems = labEntrustItemsService.getById(taskItemId);

        labItemRecordApp.setEntrustId(entrustId);
        labItemRecordApp.setTaskItemId(taskItemId);
        labItemRecordApp.setItemId(itemId);
        labItemRecordApp.setEntrustType(labEntrustItems.getEntrustType());
        labItemRecordApp.setItemName(labEntrustItems.getItemName());
        labItemRecordApp.setAuditId(labEntrustItems.getAuditId());
        labItemRecordApp.setAuditName(labEntrustItems.getAuditName());
        labItemRecordApp.setItemStatus(labEntrustItems.getItemStatus());
        labItemRecordApp.setItemImageList(labEntrustItems.getItemImageList());
        return labItemRecordApp;
    }

    /**
     * 把检测基础数据赋值labItemRecordPage中
     *
     * @param labItemRecordApp
     * @param entrustId
     * @param itemId
     * @return
     */
    public LabItemRecordApp handleItemRecordDataApp(LabItemRecordApp labItemRecordApp, String entrustId, String taskItemId, String itemId) {
        LabRecordBas recordBas = labItemsRecordBasicsService.getRecordBasOne(entrustId, taskItemId, itemId);

        for (LabItemsRecordSampleVo sam : labItemRecordApp.getItemsRecordSampleList()) {
            if ("sam_name".equals(sam.getFieldCode())) {
                String samName = recordBas.getSamName();
                if (samName != null && !"".equals(samName)) {
                    sam.setFieldValue(recordBas.getSamName());
                }
            } else if ("sam_num".equals(sam.getFieldCode())) {
                String samNum = recordBas.getSamNum();
                if (samNum != null && !"".equals(samNum)) {
                    sam.setFieldValue(recordBas.getSamNum());
                }
            } else if ("check_basis".equals(sam.getFieldCode())) {
                //检测标准不显示编码，改为显示中文名称
                sam.setFieldValue(recordBas.getBasisNum());
                LabItemsBasis itemsBasis = labItemsBasisService.getById(recordBas.getBasisId());
                if (itemsBasis != null) {
                    sam.setTextName(itemsBasis.getName());
                    sam.setAddress(itemsBasis.getAtta());
                }
            } else if ("check_time".equals(sam.getFieldCode())) {
                sam.setFieldValue(DateUtils.getDate("yyyy-MM-dd"));
            }
        }

        for (LabItemsRecordPerson per : labItemRecordApp.getItemsRecordPersonList()) {
            if ("check_person".equals(per.getFieldCode()) || "person_value1".equals(per.getFieldCode())) {
                per.setFieldValue(recordBas.getCheckPer());
            } else if ("audit_person".equals(per.getFieldCode()) || "person_value2".equals(per.getFieldCode())) {
                per.setFieldValue(recordBas.getAuditName());
            }
        }
        return labItemRecordApp;
    }

    //做实验添加设备后将相应设备的使用状态改为"使用中"
    @ApiOperation(value = "实验项目-修改设备器具使用状态", notes = "实验项目-修改设备器具使用状态")
    @GetMapping(value = "/updateStatus")
    public void updateStatus(@RequestParam List<String> devIds) {
        if (devIds.size() > 0) {
            extracted("使用中", devIds);
        }
    }

    private void extracted(String status, List<String> devIds) {
        UpdateWrapper<LabDevice> devWrapper = new UpdateWrapper<>();
        UpdateWrapper<LabUtensil> uteWrapper = new UpdateWrapper<>();
        LabDevice device = new LabDevice();
        device.setUseStatus(status);
        device.setSynFlag("1");
        devWrapper.in("id", devIds);
        labDeviceService.update(device, devWrapper);
        LabUtensil utensil = new LabUtensil();
        utensil.setUseStatus(status);
        utensil.setSynFlag("1");
        uteWrapper.in("id", devIds).or(wrapper -> wrapper.in("device_id", devIds));
        labUtensilService.update(utensil, uteWrapper);

        labDeviceService.updateStatus(status, devIds);

        if (MyEnum.sync) {
            //同步表信息
            long time = new Date().getTime();
            List<LabCronJob> jobs = new ArrayList<>();
            jobs.add(new LabCronJob("lab_device", "1", time, 1));
            jobs.add(new LabCronJob("lab_utensil", "1", time, 2));
            labCronJobService.saveBatch(jobs);
        }
    }


    /**
     * @param labItemRecordApp
     * @return
     */
    @AutoLog(value = "实验项目-更新项目检测原始数据(APP)")
    @ApiOperation(value = "实验项目-更新项目检测原始数据(APP)", notes = "实验项目-更新项目检测原始数据(APP)")
    @RequestMapping(value = "/saveOrUpdateApp", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<String> saveOrUpdateApp(@RequestBody LabItemRecordApp labItemRecordApp) throws NoSuchAlgorithmException, IOException, InvalidKeyException {

        String entrustId = labItemRecordApp.getEntrustId();
        String taskItemId = labItemRecordApp.getTaskItemId();
        String itemId = labItemRecordApp.getItemId();
        String itemStatus = labItemRecordApp.getItemStatus();

        // todo 检查实验项目
        QueryWrapper<LabEntrustItems> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("entrust_id", entrustId).eq("item_id", itemId).eq("id", taskItemId);
        List<LabEntrustItems> labEntrustItemsList = labEntrustItemsService.list(queryWrapper);
        if (labEntrustItemsList == null || labEntrustItemsList.size() <= 0) {
            return Result.error("未找到对应数据");
        }
        LabEntrustItems labEntrustItems = labEntrustItemsList.get(0);

        //1、更新样品信息
        List<LabItemsRecordSampleVo> itemsRecordSampleList = labItemRecordApp.getItemsRecordSampleList();
        List<LabItemsRecordSample> itemsRecordSamples = new ArrayList<>();
        itemsRecordSampleList.forEach(e -> {
            LabItemsRecordSample sample = new LabItemsRecordSample();
            BeanUtils.copyProperties(e, sample);
            sample.setSynFlag("1");
            itemsRecordSamples.add(sample);
        });
        if (CollectionUtil.isNotEmpty(itemsRecordSampleList)) {
            labItemsRecordSampleService.saveOrUpdateApp(entrustId, itemId, itemsRecordSamples);
        }

        //2、更新设备仪器信息
        List<LabItemsRecordDevice> itemsRecordDevList = labItemRecordApp.getItemsRecordDevList();
        if (CollectionUtil.isNotEmpty(itemsRecordDevList)) {
            List<String> idList = new ArrayList<>();
            //todo:给设备设置运行时间，
            Date date = new Date();
            itemsRecordDevList.forEach(e -> {
                Date startTime = e.getStartTime();
                Date endTime = e.getEndTime();
                if (startTime == null) {
                    startTime = date;
                }
                if (endTime == null) {
                    endTime = date;
                }
                long diffInMilliseconds = startTime.getTime() - endTime.getTime();
                long minutes = diffInMilliseconds / 6000;
                if (minutes == 0) {
                    minutes = 1;
                }
                e.setRunTime(Long.toString(minutes));
                e.setItemName(labEntrustItems.getItemName());
                e.setUserId(labEntrustItems.getUserId());
                e.setUserName(labEntrustItems.getUserName());
                e.setSamName(labEntrustItems.getSamName());
                e.setSynFlag("1");
                e.setSyType(labEntrustItems.getEntrustType());
                idList.add(e.getDevId());//获取所有设别器具的id
            });
            labItemsRecordDeviceService.saveOrUpdate(entrustId, taskItemId, itemId, itemsRecordDevList);
            //修改设备的使用状态
            if ("待复核".equals(itemStatus)) {
                if (idList.size() > 0) {
                    extracted("闲置", idList);
                }
            }
        }

        //3、更新检测条件信息
        List<LabItemsRecordNorm> itemsRecordNormList = labItemRecordApp.getItemsRecordNormList();
        if (CollectionUtil.isNotEmpty(itemsRecordNormList)) {
            itemsRecordNormList.forEach(e -> {
                e.setSynFlag("1");
            });
            labItemsRecordNormService.saveOrUpdateApp(entrustId, itemId, itemsRecordNormList);
        }

        //4、更新检测信息
        List<LabItemsRecordTarget> itemsRecordTargetList = labItemRecordApp.getItemsRecordTargetList();
        if (CollectionUtil.isNotEmpty(itemsRecordTargetList)) {
            for (LabItemsRecordTarget itemsRecordTarget : itemsRecordTargetList) {
                itemsRecordTarget.setSynFlag("1");
            }
            labItemsRecordTargetService.saveOrUpdateApp(entrustId, itemId, itemsRecordTargetList);
        }

        //5、更新检测人员信息
        List<LabItemsRecordPerson> itemsRecordPersonList = labItemRecordApp.getItemsRecordPersonList();
        if (CollectionUtil.isNotEmpty(itemsRecordPersonList)) {
            itemsRecordPersonList.forEach(e -> {
                e.setSynFlag("1");
            });
            labItemsRecordPersonService.saveOrUpdateApp(entrustId, itemId, itemsRecordPersonList);
        }

        //6、更新实验项目的信息
        if (labEntrustItems == null) {
            return Result.error("未找到对应数据");
        } else {
            labEntrustItems.setItemStatus(labItemRecordApp.getItemStatus());
            labEntrustItems.setItemFinishTime(DateUtils.getDate());
            labEntrustItems.setSynFlag("1");
            labEntrustItems.setSignatureStatus("待同步签名");
            labEntrustItems.setCodes(labItemRecordApp.getCodes());
            //设置样品的使用量
            labEntrustItems.setSamUsed(labItemRecordApp.getSamUsed());
            //设置实验开始和结束时间 todo:
            labEntrustItems.setItemStartTime(new Date(labItemRecordApp.getItemStartTime()));
            labEntrustItems.setItemFinishTime(new Date(labItemRecordApp.getItemFinishTime()));
            labEntrustItems.setItemImageList(labItemRecordApp.getItemImageList());
            //todo 更新实验项目的信息
            labEntrustItemsService.updateById(labEntrustItems);


            List<LabNotify> labNotifies = labNotifyService.list(new LambdaQueryWrapper<LabNotify>()
                    .eq(LabNotify::getEntrustId, entrustId)
                    .eq(LabNotify::getTaskId, itemId)
                    .eq(LabNotify::getNotTitlle, "实验"));
            if (labNotifies != null) {
                for (LabNotify labNotify : labNotifies) {
                    labNotify.setFinish(1);
                    labNotify.setSynFlag("1");
                    labNotifyService.updateById(labNotify);
                }
            }

            if ("待复核".equals(itemStatus)) {
                //todo 更新实验项目的检测指标结果
                generatResultApp(labEntrustItems.getId(), labEntrustItems.getBasisId(), itemsRecordTargetList);
                //todo 更新样品状态
                labEntrustSampleService.updateSample(taskItemId);
                //todo 样品流传记录
                labSampleRecordService.addLabRecords(entrustId, labEntrustItems);

                String notName = labEntrustItems.getSamName();
                String itemName = labEntrustItems.getItemName();
                String notTitle = "实验复核";
                String taskName = "实验[" + labEntrustItems.getItemName() + "]" + "复核";
                String userId = labItemRecordApp.getAuditId();
                makeNotify(notName, itemName, notTitle, itemId, taskName, entrustId, userId, itemId);
            }


            if (MyEnum.sync) {
                //同步表信息
                long time = new Date().getTime();
                List<LabCronJob> jobs = new ArrayList<>();
                jobs.add(new LabCronJob("lab_items_record_device", "2", " task_id='" + entrustId + "' and task_item_id='" + taskItemId + "'", time, 1));
                jobs.add(new LabCronJob("lab_items_record_sample", "1", time, 2));
                jobs.add(new LabCronJob("lab_items_record_device", "0", time, 3));
                jobs.add(new LabCronJob("lab_items_record_norm", "1", time, 4));
                jobs.add(new LabCronJob("lab_items_record_target", "1", time, 5));
                jobs.add(new LabCronJob("lab_items_record_person", "1", time, 6));
                jobs.add(new LabCronJob("lab_entrust_items", "1", time, 7));
                jobs.add(new LabCronJob("lab_entrust_items_index", "1", time, 8));
                jobs.add(new LabCronJob("lab_notify", "1", time, 9));
                jobs.add(new LabCronJob("lab_notify", "0", time, 10));
                jobs.add(new LabCronJob("lab_sample_record", "0", time, 11));
                jobs.add(new LabCronJob("lab_entrust_sample", "1", time, 12));
                labCronJobService.saveBatch(jobs);
            }
        }
        if ("待复核".equals(itemStatus)) {
            return Result.OK("实验完成！");
        } else {
            return Result.OK("保存成功！");
        }

    }

    /**
     * pc端做实验提交实验原始数据自动检测生成指标结果
     *
     * @param taskItemsId
     * @param labRecordTargList
     */
    private void generatResultPc(String taskItemsId, String basisId, List<LabRecordTarg> labRecordTargList) {
        QueryWrapper<LabEntrustItemsIndex> indexWrapper = new QueryWrapper<>();
        indexWrapper.eq("task_items_id", taskItemsId);
        indexWrapper.ne("index_basis", "无");
        List<LabEntrustItemsIndex> labEntrustItemsIndexList = labEntrustItemsIndexService.list(indexWrapper);

        if (labEntrustItemsIndexList.size() > 0) {
            for (LabEntrustItemsIndex index : labEntrustItemsIndexList) {
                String index_code = index.getIndexCode();
                for (LabRecordTarg targs : labRecordTargList) {
                    for (LabItemsRecordTarget target : targs.getItemsRecordTargetList()) {
                        if (index_code != null && index_code.equals(target.getFieldCode())) {
                            String type = index.getIndexType();
                            String basis = index.getIndexBasis();
                            String finalValue = target.getFieldValue();
                            index.setSynFlag("1");
                            index.setItemResult(finalValue);
                            index.setItemDecide(compareResult(type, basis, finalValue));
                            break;
                        }
                    }
                }
            }
            labEntrustItemsIndexService.updateBatchById(labEntrustItemsIndexList);
        } else {
            for (LabRecordTarg targs : labRecordTargList) {
                for (LabItemsRecordTarget target : targs.getItemsRecordTargetList()) {
                    if ("final_value".equals(target.getFieldCode()) || "final_value1".equals(target.getFieldCode()) || "final_value2".equals(target.getFieldCode())) {
                        LabEntrustItemsIndex labEntrustItemsIndex = new LabEntrustItemsIndex();
                        labEntrustItemsIndex.setTaskId(target.getTaskId());
                        labEntrustItemsIndex.setTaskItemsId(taskItemsId);
                        labEntrustItemsIndex.setItemId(target.getItemId());
                        labEntrustItemsIndex.setBasisId(basisId);
                        if ("final_value1".equals(target.getFieldCode()) || "final_value2".equals(target.getFieldCode())) {
                            labEntrustItemsIndex.setIndexName(target.getFieldName());
                        } else {
                            labEntrustItemsIndex.setIndexName(null);
                        }
                        labEntrustItemsIndex.setIndexCode(target.getFieldCode());
                        labEntrustItemsIndex.setIndexBasis("无");
                        labEntrustItemsIndex.setIndexType(null);
                        labEntrustItemsIndex.setItemResult(target.getFieldValue());
                        labEntrustItemsIndex.setItemDecide("-");
                        labEntrustItemsIndex.setSynFlag("0");
                        labEntrustItemsIndexService.save(labEntrustItemsIndex);
                        break;
                    }
                }
            }
        }
    }

    /**
     * app端做实验提交实验原始数据自动检测生成指标结果
     *
     * @param taskItemsId
     * @param itemsRecordTargetList
     */
    private void generatResultApp(String taskItemsId, String basisId, List<LabItemsRecordTarget> itemsRecordTargetList) {
        QueryWrapper<LabEntrustItemsIndex> indexWrapper = new QueryWrapper<>();
        indexWrapper.eq("task_items_id", taskItemsId);
        indexWrapper.ne("index_basis", "无");
        List<LabEntrustItemsIndex> labEntrustItemsIndexList = labEntrustItemsIndexService.list(indexWrapper);

        if (labEntrustItemsIndexList.size() > 0) {
            for (LabEntrustItemsIndex index : labEntrustItemsIndexList) {
                String index_code = index.getIndexCode();
                for (LabItemsRecordTarget target : itemsRecordTargetList) {
                    if (index_code != null && index_code.equals(target.getFieldCode())) {
                        String type = index.getIndexType();
                        String basis = index.getIndexBasis();
                        String finalValue = target.getFieldValue();
                        index.setSynFlag("1");
                        index.setItemResult(finalValue);
                        index.setItemDecide(compareResult(type, basis, finalValue));
                        break;
                    }
                }
            }
            labEntrustItemsIndexService.updateBatchById(labEntrustItemsIndexList);
        } else {
            for (LabItemsRecordTarget target : itemsRecordTargetList) {
                if ("final_value".equals(target.getFieldCode()) || "final_value1".equals(target.getFieldCode()) || "final_value2".equals(target.getFieldCode())) {
                    LabEntrustItemsIndex labEntrustItemsIndex = new LabEntrustItemsIndex();
                    labEntrustItemsIndex.setTaskId(target.getTaskId());
                    labEntrustItemsIndex.setTaskItemsId(taskItemsId);
                    labEntrustItemsIndex.setItemId(target.getItemId());
                    labEntrustItemsIndex.setBasisId(basisId);
                    if ("final_value1".equals(target.getFieldCode()) || "final_value2".equals(target.getFieldCode())) {
                        labEntrustItemsIndex.setIndexName(target.getFieldName());
                    } else {
                        labEntrustItemsIndex.setIndexName(null);
                    }
                    labEntrustItemsIndex.setIndexCode(target.getFieldCode());
                    labEntrustItemsIndex.setIndexBasis("无");
                    labEntrustItemsIndex.setIndexType(null);
                    labEntrustItemsIndex.setItemResult(target.getFieldValue());
                    labEntrustItemsIndex.setItemDecide("-");
                    labEntrustItemsIndex.setSynFlag("0");
                    labEntrustItemsIndexService.save(labEntrustItemsIndex);
                    break;
                }
            }
        }
    }

    /**
     * 根据填报的原始记录检测实验指标是否合格
     *
     * @param type
     * @param basis
     * @param finalValue
     */
    private String compareResult(String type, String basis, String finalValue) {
        String decide = "不合格";
        if ("大于等于".equals(type) || "小于等于".equals(type) || "大于".equals(type) || "小于".equals(type) || "区间".equals(type)) {
            if (finalValue != null && NumberUtil.isNumeric(finalValue)) {//判断实验结果是不是数字
                if ("大于等于".equals(type)) {
                    double aDouble = Double.parseDouble(basis.substring(1));// 从第二个字符开始将剩余部分解析为浮点数
                    double final_value = Double.parseDouble(finalValue);
                    if (final_value >= aDouble) {
                        decide = "合格";
                    }
                } else if ("大于".equals(type)) {
                    double aDouble = Double.parseDouble(basis.substring(1));// 从第二个字符开始将剩余部分解析为浮点数
                    double final_value = Double.parseDouble(finalValue);
                    if (final_value > aDouble) {
                        decide = "合格";
                    }
                } else if ("小于等于".equals(type)) {
                    double aDouble = Double.parseDouble(basis.substring(1));// 从第二个字符开始将剩余部分解析为浮点数
                    double final_value = Double.parseDouble(finalValue);
                    if (final_value <= aDouble) {
                        decide = "合格";
                    }
                } else if ("小于".equals(type)) {
                    double aDouble = Double.parseDouble(basis.substring(1));// 从第二个字符开始将剩余部分解析为浮点数
                    double final_value = Double.parseDouble(finalValue);
                    if (final_value < aDouble) {
                        decide = "合格";
                    }
                } else if ("区间".equals(type)) {
                    String[] strings = basis.split("~");
                    double lower_value = Double.parseDouble(strings[0]);
                    double upper_value = Double.parseDouble(strings[1]);
                    double final_value = Double.parseDouble(finalValue);
                    if (final_value >= lower_value && final_value <= upper_value) {
                        decide = "合格";
                    }
                }
            }
        } else if ("描述".equals(type)) {
            if (basis.contains(finalValue)) {
                decide = "合格";
            }
        }
        return decide;
    }

    @ApiOperation(value = "实验项目-重复实验增加新项目", notes = "实验项目-重复实验增加新项目")
    @GetMapping(value = "/getNewEntrusItem")
    public Result<LabEntrustItems> getNewEntrusItem(@RequestParam(name = "entrustId") String entrustId, @RequestParam(name = "itemId") String itemId) {

        QueryWrapper<LabEntrustItems> itemsQueryWrapper = new QueryWrapper<>();
        itemsQueryWrapper.eq("entrust_id", entrustId);
        itemsQueryWrapper.eq("item_id", itemId);
        itemsQueryWrapper.eq("item_status", "已实验");
        List<LabEntrustItems> labEntrustItemsList = labEntrustItemsService.list(itemsQueryWrapper);
        if (labEntrustItemsList == null || labEntrustItemsList.size() == 0) {
            return Result.error("未找到对应数据");
        }
        LabEntrustItems labEntrustItems = labEntrustItemsList.get(0);
        QueryWrapper<LabEntrustItemsIndex> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("task_items_id", labEntrustItems.getId());
        List<LabEntrustItemsIndex> labEntrustItemsIndexList = labEntrustItemsIndexService.list(queryWrapper);

        labEntrustItems.setId(null);
        labEntrustItems.setCreateBy(null);
        labEntrustItems.setCreateTime(null);
        labEntrustItems.setUpdateTime(null);
        labEntrustItems.setUpdateBy(null);
        labEntrustItems.setSysOrgCode(null);
        labEntrustItems.setItemStatus("待实验");
        labEntrustItems.setItemStartTime(null);
        labEntrustItems.setItemFinishTime(null);
        labEntrustItems.setSynFlag("0");
        labEntrustItems.setItemImageList(null);
        labEntrustItems.setCodes(null);
        labEntrustItems.setSignatureStatus("待同步签名");
        labEntrustItemsService.save(labEntrustItems);

        for (LabEntrustItemsIndex labEntrustItemsIndex : labEntrustItemsIndexList) {
            labEntrustItemsIndex.setId(null);
            labEntrustItemsIndex.setCreateTime(null);
            labEntrustItemsIndex.setItemResult(null);
            labEntrustItemsIndex.setItemDecide(null);
            labEntrustItemsIndex.setUpdateBy(null);
            labEntrustItemsIndex.setUpdateTime(null);
            labEntrustItemsIndex.setSynFlag("0");
            labEntrustItemsIndex.setTaskItemsId(labEntrustItems.getId());
        }

        labEntrustItemsIndexService.saveBatch(labEntrustItemsIndexList);
        //插入项目模板-样品信息
        labItemsRecordSampleService.insertSamData(labEntrustItems);
        //插入项目模板-检测条件信息
        labItemsRecordNormService.insertNormData(labEntrustItems);
        //插入项目模板-检测信息
        labItemsRecordTargetService.insertTargetData(labEntrustItems);
        //插入项目模板-人员信息
        labItemsRecordPersonService.insertPersonData(labEntrustItems);

//        String entrustId= labEntrustItems.getEntrustId();
//        String taskItemId= labEntrustItems.getId();
//        String itemId= labEntrustItems.getItemId();
//        LabItemRecordApp labItemRecordApp = getLabItemRecord(entrustId,taskItemId,itemId);

        if (MyEnum.sync) {
            //同步表信息
            long time = new Date().getTime();
            List<LabCronJob> jobs = new ArrayList<>();
            jobs.add(new LabCronJob("lab_entrust_items", "0", time, 1));
            jobs.add(new LabCronJob("lab_entrust_items_index", "0", time, 2));
            jobs.add(new LabCronJob("lab_items_record_sample", "0", time, 3));
            jobs.add(new LabCronJob("lab_items_record_norm", "0", time, 4));
            jobs.add(new LabCronJob("lab_items_record_target", "0", time, 5));
            jobs.add(new LabCronJob("lab_items_record_person", "0", time, 6));
            labCronJobService.saveBatch(jobs);
        }

        return Result.OK(labEntrustItems);
    }

    /**
     * 待检样品数量
     *
     * @param userId
     * @return
     */
    @ApiOperation(value = "样品信息-待检样品数量", notes = "样品信息-待检样品数量")
    @GetMapping(value = "/getWaitSamNum")
    public Result<LabSamItemPage> getWaitSamNum(@RequestParam(name = "userId") String userId) {
        LabSamItemPage labSamItemPage = iLabTaskAllotService.getWaitSamNum(userId);
        return Result.OK(labSamItemPage);
    }

    /**
     * 待检样品列表
     *
     * @param userId
     * @return
     */
    @ApiOperation(value = "样品信息-待检样品列表", notes = "样品信息-待检样品列表")
    @GetMapping(value = "/getWaitSamList")
    public Result<List<LabEntrustSample>> getWaitSamList(@RequestParam(name = "userId") String userId) {
        List<LabEntrustSample> labEntrustSamples = iLabTaskAllotService.getWaitSamList(userId);
        return Result.OK(labEntrustSamples);
    }

    /**
     * 个人工作量统计：
     * 待检项目数，当月检测数，当月实验时间，当月加班时间，累计检测数，累计实验时间
     * 统计图：每月实验数，每月实验时间
     */
    @GetMapping(value = "/personalCount")
    public Result getPersonalCount(@RequestParam(name = "userId") String id, @RequestParam(name = "year") String yearValue) {

        Map<String, Object> map = labEntrustItemsService.countMessage(id, yearValue);
        return Result.ok(map);
    }

    /**
     * 首页根据月份统计工作量
     *
     * @param year
     * @return
     */
    @GetMapping(value = "/monthCount")
    public Result<Map<String, Object>> queryMonth(@RequestParam String year) {
        Map<String, Object> map = labEntrustItemsService.countYear(year);
        return Result.ok(map);
    }


    /**
     * 实验数据统计（样品、项目）
     *
     * @return
     */
    @GetMapping(value = "/samItemCount")
    public Result<LabSamItemPage> getSamAndItemCount(@RequestParam(name = "checkType") String checkType, @RequestParam(name = "startTime") String startTime, @RequestParam(name = "endTime") String endTime) {
        String date = DateUtils.date2Str(new SimpleDateFormat("yyyy-MM"));
        LabSamItemPage labSamItemPage = iLabTaskAllotService.querySamItemCount(date, checkType, startTime, endTime);
        return Result.ok(labSamItemPage);
    }

    @GetMapping(value = "/monthSamItemCount")
    public Result<Map<String, Object>> querySamItemMonth(@RequestParam String year) {
        Map<String, Object> map = iLabTaskAllotService.querySamItemYear(year);
        return Result.ok(map);
    }


}
